﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.EntityFrameworkCore.EFPlus;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Abp.UI;
using Abp.Web.Models.AbpUserConfiguration;
using ARchGL.Platform.Authorization;
using ARchGL.Platform.Authorization.Accounts;
using ARchGL.Platform.Authorization.Roles;
using ARchGL.Platform.Authorization.Users;
using ARchGL.Platform.Configuration;
using ARchGL.Platform.Core;
using ARchGL.Platform.Dtos;
using ARchGL.Platform.FileServer;
using ARchGL.Platform.Juneng;
using ARchGL.Platform.Juneng.InputDtos.ProjectUser;
using ARchGL.Platform.Juneng.ViewDtos;
using ARchGL.Platform.Mpp;
using ARchGL.Platform.Mpp.InputModels;
using ARchGL.Platform.Qianbian;
using ARchGL.Platform.Utils;
using ARchGL.Platform.Validation;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace ARchGL.Platform.Application
{
    /// <summary>
    /// 项目 实现
    /// </summary>
    [AbpAuthorize]
    public class ProjectsAppService : PlatformAppServiceBase, IProjectsAppService
    {
        #region 实例化

        private readonly IConfigurationRoot appConfiguration;
        private readonly IRepository<Projects, Guid> projectsRepository;
        private readonly IRepository<QB_Projects, Guid> qb_projectsRepository;
        private readonly IRepository<ProjectModelGroups, Guid> projectModelGroupsRepository;
        private readonly IRepository<ProjectUsers, Guid> projectUsersRepository;
        private readonly IRepository<ProjectModels, Guid> projectsModelsRepository;
        private readonly IRepository<ProjectViewPorts, Guid> projectViewPortsRepository;
        private readonly IRepository<Role> roleRepository;
        private readonly IRepository<UserRoleExtend, long> userRoleRepository;
        private readonly IRepository<OrganizationUnitExtend, long> organizationUnitRepository;
        private readonly IRepository<UserOrganizationUnitExtend, long> userOrganizationUnitRepository;
        private readonly IRepository<User, long> userRepository;
        private readonly ISecurityChecksAppService securityChecksAppService;
        private readonly IRepository<SecurityCheckItems, Guid> securityCheckItemsRepository;
        private readonly IAccountAppService accountAppService;
        private readonly IProjectInfoApi projectInfoApi;
        private readonly IRepository<DocumentLibrarys, Guid> documentLibrarysRepository;
        private readonly IMppAppService mppAppService;
        public ProjectsAppService(
            IHostingEnvironment env,
            IRepository<Projects, Guid> _projectsRepository,
            IRepository<QB_Projects, Guid> _qb_projectsRepository,
            IRepository<ProjectModelGroups, Guid> _projectModelGroupsRepository,
            IRepository<ProjectUsers, Guid> _projectUsersRepository,
            IRepository<ProjectModels, Guid> _projectsModelsRepository,
            IRepository<ProjectViewPorts, Guid> _projectViewPortsRepository,
            IRepository<Role> _roleRepository,
            IRepository<UserRoleExtend, long> _userRoleRepository,
            IRepository<OrganizationUnitExtend, long> _organizationUnitRepository,
            IRepository<UserOrganizationUnitExtend, long> _userOrganizationUnitRepository,
            IRepository<User, long> _userRepository,
            ISecurityChecksAppService _securityChecksAppService,
            IRepository<SecurityCheckItems, Guid> _securityCheckItemsRepository,
            IAccountAppService _accountAppService,
            IProjectInfoApi _projectInfoApi,
            IRepository<DocumentLibrarys, Guid> _documentLibrarysRepository,
             IMppAppService _mppAppService)
        {
            appConfiguration = env.GetAppConfiguration();
            projectsRepository = _projectsRepository;
            qb_projectsRepository = _qb_projectsRepository;
            projectModelGroupsRepository = _projectModelGroupsRepository;
            projectsModelsRepository = _projectsModelsRepository;
            projectViewPortsRepository = _projectViewPortsRepository;
            projectUsersRepository = _projectUsersRepository;
            roleRepository = _roleRepository;
            userRoleRepository = _userRoleRepository;
            organizationUnitRepository = _organizationUnitRepository;
            userOrganizationUnitRepository = _userOrganizationUnitRepository;
            userRepository = _userRepository;
            securityChecksAppService = _securityChecksAppService;
            securityCheckItemsRepository = _securityCheckItemsRepository;
            accountAppService = _accountAppService;
            projectInfoApi = _projectInfoApi;
            documentLibrarysRepository = _documentLibrarysRepository;
            mppAppService = _mppAppService;
        }

        #endregion

        #region 项目

        /// <summary>
        /// 创建/编辑项目
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateOrModifyProject(ProjectsDto input)
        {
            #region 表单验证方法

            string error = Validate.ValidateString(new CustomValidate
            {
                FieldName = "项目名称",
                FieldValue = input.Name,
                IsRequired = true
            });
            if (!error.IsNullOrWhiteSpace()) throw new UserFriendlyException(error);

            #endregion

            if (input.Id == Guid.Empty)
            {
                var currentUser = await GetCurrentUserAsync();
                var entity = ObjectMapper.Map<Projects>(input);
                entity.Mark = entity.Mark != EnumTrue.是 ? EnumTrue.否 : EnumTrue.是;  // 1关注；2未关注
                entity.CreatorUserId = currentUser.PrimaryId;
                var result = await projectsRepository.InsertAsync(entity);

                await InitSecurityCheckItemsByProject(result);

                //初始化文件夹(项目工程检验批 目录)
                var parentDocument = await InitDocumentByProject(entity, null, null);

                //将创建者加入项目成员
                await AddOrModifyUserToProject(new AddOrModifyUserToProjectInput
                {
                    ProjectId = result.Id,
                    UserId = currentUser.PrimaryId,
                    Position = "",
                    PermissionArray = input.PermissionArray
                });
            }
            else //只编辑项目信息
            {
                var entity = await projectsRepository.FirstOrDefaultAsync(x => x.Id == input.Id);
                if (entity == null) throw new UserFriendlyException(L("TheProjectDoesNotExist"), L("PleaseRefreshThePageAndTryAgain"));
                entity.Name = input.Name;
                entity.Code = input.Code;
                entity.ImageUrl = input.ImageUrl;
                entity.Description = input.Description;
                entity.Address = input.Address;
                entity.Type = input.Type;
                entity.Status = input.Status;
                entity.Mark = input.Mark == EnumTrue.是 ? EnumTrue.是 : EnumTrue.否;
                entity.Location = input.Location;

                entity.CompanyName = input.CompanyName;
                entity.CompanyLinkman = input.CompanyLinkman;
                entity.CompanyLinkphone = input.CompanyLinkphone;
                entity.CompanyAddress = input.CompanyAddress;

                entity.DepartName = input.DepartName;
                entity.TotalInCome = input.TotalInCome;
                entity.TakeLimit = input.TakeLimit;
                entity.IsImportant = input.IsImportant == EnumTrue.是 ? EnumTrue.是 : EnumTrue.否;
                entity.IsApprove = input.IsApprove == EnumTrue.是 ? EnumTrue.是 : EnumTrue.否;
                await projectsRepository.UpdateAsync(entity);
            }
        }

        /// <summary>初始化项目检查相关配置信息</summary>
        private async Task InitSecurityCheckItemsByProject(Projects project, bool isReset = false)
        {
            if (isReset)
                await securityCheckItemsRepository.DeleteAsync(x => x.ProjectId == project.Id && x.Type == EnumCheckItemType.检查性质);

            //质量检查
            var parent = await securityCheckItemsRepository.InsertAsync(new SecurityCheckItems { Name = "质量检查", Type = EnumCheckItemType.检查性质, ProjectId = project.Id, ParentId = Guid.Empty });
            var child = new List<SecurityCheckItems> { new SecurityCheckItems { Name = "施工质量", Type = EnumCheckItemType.检查性质, ProjectId = project.Id, ParentId = parent.Id } };
            await securityCheckItemsRepository.BatchInsert(child);

            //安全检查
            parent = await securityCheckItemsRepository.InsertAsync(new SecurityCheckItems { Name = "安全检查", Type = EnumCheckItemType.检查性质, ProjectId = project.Id, ParentId = Guid.Empty });
            child = new List<SecurityCheckItems> { new SecurityCheckItems { Name = "施工安全", Type = EnumCheckItemType.检查性质, ProjectId = project.Id, ParentId = parent.Id } };
            await securityCheckItemsRepository.BatchInsert(child);

            //进度检查
            parent = await securityCheckItemsRepository.InsertAsync(new SecurityCheckItems { Name = "进度检查", Type = EnumCheckItemType.检查性质, ProjectId = project.Id, ParentId = Guid.Empty });
            child = new List<SecurityCheckItems> { new SecurityCheckItems { Name = "施工进度", Type = EnumCheckItemType.检查性质, ProjectId = project.Id, ParentId = parent.Id } };
            await securityCheckItemsRepository.BatchInsert(child);
        }

        /// <summary>
        /// 项目 关注/取消关注，根据当前状态反转
        /// </summary>
        /// <param name="input">项目主键</param>
        /// <returns></returns>
        public async Task MarkProject(Guid input)
        {
            var entity = await projectsRepository.FirstOrDefaultAsync(x => x.Id == input);
            if (entity == null) throw new UserFriendlyException(L("TheProjectDoesNotExist"), L("PleaseRefreshThePageAndTryAgain"));
            entity.Mark = entity.Mark == EnumTrue.是 ? EnumTrue.否 : EnumTrue.是;
        }

        /// <summary>
        /// 删除项目
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task RemoveProject(Guid input)
        {
            var entity = await projectsRepository.FirstOrDefaultAsync(x => x.Id == input);
            if (entity == null) throw new UserFriendlyException(L("TheProjectDoesNotExist", "PleaseRefreshThePageAndTryAgain"));
            await projectsRepository.DeleteAsync(entity);
        }

        /// <summary>
        /// 查询项目-分页数据集合
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ProjectsDto>> QueryProjectPagedList(ProjectsInput input)
        {
            var projectQuery = projectsRepository.GetAll()
                        .WhereIf(input.Type > 0, x => x.Type == input.Type)
                        .WhereIf(input.Status > 0, x => x.Status == input.Status)
                        .WhereIf(input.Mark > 0, x => x.Mark == input.Mark)
                        .WhereIf(input.IsImportant > 0, x => x.IsImportant == input.IsImportant)
                        .WhereIf(input.IsApprove > 0, x => x.IsApprove == input.IsApprove)
                        .WhereCreationTimeRange1(input.CreationTimeRange)
                        .WhereIf(!input.Filter.IsNullOrWhiteSpace(),
                            x => x.Name.Contains(input.Filter) || x.Code.Contains(input.Filter) ||
                            x.Address.Contains(input.Filter) || x.CompanyName.Contains(input.Filter)
                            || x.CompanyLinkman.Contains(input.Filter) || x.CompanyLinkphone.Contains(input.Filter));

            //当前登录信息
            // var userIdentity = new UserIdentifier(AbpSession.TenantId, AbpSession.UserId.Value);
            var user = await GetCurrentUserAsync(); //await UserManager.GetUserAsync(userIdentity);

            //管理者admin权限可以查看所有项目,非管理者只查与自己有关的项目(且)
            if (!await UserManager.IsInRoleAsync(user, StaticRoleNames.Tenants.Admin))
            {
                projectQuery = projectQuery
                    .WhereIf(input.CheckType == EnumCheckType.巡检, x => PermissionChecker.IsGranted(AppPermissions.APJ_Project_Check) && projectUsersRepository.GetAll().Any(u => u.UserId == user.PrimaryId && u.ProjectId == x.Id))
                    .WhereIf(input.CheckType == EnumCheckType.自检, x => x.CreatorUserId == user.PrimaryId || projectUsersRepository.GetAll().Any(u => u.UserId == user.PrimaryId && u.ProjectId == x.Id && u.PermissionArray.Contains(AppPermissions.APJ_PI_CreateSelf)))
                    .WhereIf(input.CheckType != EnumCheckType.巡检 && input.CheckType != EnumCheckType.自检, x => x.CreatorUserId == user.PrimaryId || projectUsersRepository.GetAll().Any(u => u.UserId == user.PrimaryId && u.ProjectId == x.Id));
            }

            var result = await projectQuery.OrderByDescending(x => x.CreationTime).PageByAsync(input);

            return new PagedResultDto<ProjectsDto>(projectQuery.Count(),
                ObjectMapper.Map<List<ProjectsDto>>(result));
        }

        /// <summary>
        /// 查询项目-分页数据集合
        /// (巡检/自检相关的项目)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ProjectsDto>> QueryProjectPagedListForCheck(ProjectsInput input)
        {
            return await QueryProjectPagedList(input);
        }

        /// <summary>
        /// 获取项目详情信息
        /// </summary>
        /// <param name="input">项目编号</param>
        /// <returns></returns>
        public async Task<ProjectDetailsDto> QueryProjectDetailById(Guid input)
        {
            var entity = await projectsRepository.FirstOrDefaultAsync(t => t.Id == input);
            if (entity == null) throw new UserFriendlyException(L("TheProjectDoesNotExist", "PleaseRefreshThePageAndTryAgain"));
            ProjectDetailsDto dto = ObjectMapper.Map<ProjectDetailsDto>(entity);
            if (!dto.Code.IsNullOrWhiteSpace())
                dto.QB_ProjectId = qb_projectsRepository.GetAll().FirstOrDefault(x => x.Code == dto.Code)?.Id;
            return dto;
        }

        /// <summary>
        /// 获取项目分类枚举
        /// </summary>
        /// <returns></returns>
        public dynamic GetEnumProjectTypeList()
        {
            return CommonHelper.ReadEnum(typeof(EnumProjectType)).ToList();
        }

        /// <summary>
        /// 获取项目状态枚举
        /// </summary>
        /// <returns></returns>
        public dynamic GetEnumProjectStatusList()
        {
            return CommonHelper.ReadEnum(typeof(EnumProjectStatus)).ToList();
        }

        #endregion

        #region 项目用户

        /// <summary>
        /// 添加用户至项目
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Guid> AddOrModifyUserToProject(AddOrModifyUserToProjectInput input)
        {
            if (input.Id == Guid.Empty)
            {
                if (projectUsersRepository.GetAll().Any(t => t.ProjectId == input.ProjectId && t.UserId == input.UserId))
                    throw new UserFriendlyException("该成员已经存在，请重新输入");

                var entity = ObjectMapper.Map<ProjectUsers>(input);
                entity.CreatorUserId = UserManager.PrimaryId;
                entity.PermissionArray = input.PermissionArray.SerializeObject();

                //添加
                return await projectUsersRepository.InsertAndGetIdAsync(entity);
            }
            else
            {
                //修改
                var entity = await projectUsersRepository.FirstOrDefaultAsync(x => x.Id == input.Id);
                if (entity != null)
                {
                    entity.Position = input.Position;
                    if (input.PermissionArray != null)
                        entity.PermissionArray = input.PermissionArray.SerializeObject();
                    await projectUsersRepository.UpdateAsync(entity);
                }
                return entity.Id;
            }
        }

        /// <summary>
        /// 删除项目用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task RemoveUserOnProject(RemoveUserOnProjectInput input)
        {
            if (input == null || input.ProjectId == Guid.Empty || input.UserId != Guid.Empty) throw new UserFriendlyException(L("NoParam", L("InvalidFormMessage")));

            var project = await projectsRepository.FirstOrDefaultAsync(x => x.Id == input.ProjectId);
            if (project != null && project.CreatorUserId.HasValue && input.UserId == project.CreatorUserId)
            {
                throw new UserFriendlyException("当前用户名下有活动项目，请先删除相关项目");
            }

            var entity = await projectUsersRepository.FirstOrDefaultAsync(x => x.ProjectId == input.ProjectId && x.UserId == input.UserId);
            if (entity != null)
            {
                await projectUsersRepository.DeleteAsync(entity);
            }
        }

        /// <summary>
        /// 批量删除项目用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task BatchRemoveUserOnProject(BatchRemoveUserOnProjectInput input)
        {
            if (input.UserIdList == null || input.UserIdList.Count <= 0) throw new UserFriendlyException(L("NoParam"), L("InvalidFormMessage"));

            var project = await projectsRepository.FirstOrDefaultAsync(x => x.Id == input.ProjectId);
            if (project != null && project.CreatorUserId.HasValue && input.UserIdList.Contains(project.CreatorUserId.Value))
            {
                throw new UserFriendlyException("当前用户名下有活动项目，请先删除相关项目");
            }

            await projectUsersRepository.BatchDeleteAsync(x => x.ProjectId == input.ProjectId && input.UserIdList.Contains(x.UserId));
        }

        /// <summary>
        /// 获取项目成员列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ProjectUsersDto>> QueryProjectUsersPagedList(ProjectUsersInput input)
        {
            if (input == null || input.ProjectId == Guid.Empty) throw new UserFriendlyException(L("NoParam"), L("InvalidFormMessage"));

            var result = new List<ProjectUsersDto>();
            #region 用户信息筛选

            var query = from pu in projectUsersRepository.GetAll().WhereIf(input.ProjectId != Guid.Empty, x => x.ProjectId == input.ProjectId)
                        join u in UserManager.Users on pu.UserId equals u.PrimaryId
                        where pu.ProjectId == input.ProjectId
                        select new ProjectUsersDto
                        {
                            Id = pu.Id,
                            UserId = u.PrimaryId,
                            CreationTime = pu.CreationTime,
                            EmailAddress = u.EmailAddress,
                            Name = u.Name,
                            UserName = u.UserName,
                            OrganizationUnitName = "",
                            PhoneNumber = u.PhoneNumber,
                            RoleName = "", //role.DisplayName,
                            Avatar = u.Avatar,
                            Position = pu.Position,
                            PermissionArray = pu.PermissionArray
                        };

            if (!input.Filter.IsNullOrWhiteSpace())
                query = query.Where(x => x.Name.Contains(input.Filter)
                || x.EmailAddress.Contains(input.Filter)
                || x.PhoneNumber.Contains(input.Filter)
                || x.Position.Contains(input.Filter)
                );

            var queryResult = await query.OrderByDescending(x => x.CreationTime).PageByAsync(input);
            result = queryResult.ToList();

            #endregion

            #region New 部门 + 角色 + 结果

            var userIdList = result.Select(x => x.UserId).ToList();

            //部门
            var organizationUnitList = (from uou in userOrganizationUnitRepository.GetAll()
                                        join ou in organizationUnitRepository.GetAll() on uou.OrganizationUnitPrimaryId equals ou.PrimaryId into uouJoined
                                        from ou in uouJoined.DefaultIfEmpty()
                                        where userIdList.Contains(uou.UserPrimaryId)

                                        select new
                                        {
                                            uou.UserPrimaryId,
                                            uou.OrganizationUnitId,
                                            ou.Code,
                                            ou.DisplayName
                                        }).ToList();

            //角色
            var roleList = (from ur in userRoleRepository.GetAll()
                            join r in roleRepository.GetAll() on ur.RoleId equals r.Id into urJoined
                            from r in urJoined.DefaultIfEmpty()
                            where userIdList.Contains(ur.UserPrimaryId)

                            select new
                            {
                                ur.UserPrimaryId,
                                r.DisplayName
                            }).ToList();

            if (result.Any())
            {
                for (int i = 0; i < result.Count; i++)
                {
                    var user = result[i];
                    try
                    {
                        //获取直属部门
                        var entityOrgan = organizationUnitList.OrderByDescending(x => x.Code).FirstOrDefault(x => x.UserPrimaryId == user.UserId);
                        user.OrganizationUnitName = entityOrgan?.DisplayName;
                    }
                    catch { }

                    try
                    {
                        //获取人员角色
                        var entityRole = roleList.FirstOrDefault(x => x.UserPrimaryId == user.UserId);
                        user.RoleName = entityRole?.DisplayName;
                    }
                    catch { }
                }
            }

            #endregion

            return new PagedResultDto<ProjectUsersDto>(query.Count(),
                 ObjectMapper.Map<List<ProjectUsersDto>>(result)
            );
        }

        /// <summary>
        /// 获取项目成员权限
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<string> QueryPermissionByProjectUser(QueryPermissionByProjectUserInput input)
        {
            var userId = input.UserId.HasValue ? input.UserId : UserManager.PrimaryId;
            var entity = await projectUsersRepository.FirstOrDefaultAsync(x => x.ProjectId == input.ProjectId && x.UserId == userId);
            if (entity == null) return "";
            return entity.PermissionArray;
        }

        /// <summary>
        /// 检查并初始化无成员项目状态
        /// </summary>
        /// <returns>初始化项目数</returns>
        public async Task<int> DoCheckProjectUserTask()
        {
            //查询项目成员权限
            List<string> permissionArray = new List<string>();
            try
            {
                AbpUserAuthConfigDto authconfig = await accountAppService.GetAllPermissions();
                permissionArray = authconfig.GrantedPermissions.Keys.Where(t => t.Contains(AppPermissions.APJ_PI)).ToList();
            }
            catch
            {
                throw new UserFriendlyException("抱歉，您没有操作权限");
            }
            List<Guid> result = new List<Guid>();
            var queryProject = projectsRepository.GetAll().Where(pro => pro.CreatorUserId.HasValue && pro.CreatorUserId != Guid.Empty && !projectUsersRepository.GetAll().Any(pu => pu.UserId == pro.CreatorUserId && pu.ProjectId == pro.Id));

            if (await queryProject.AnyAsync())
            {
                await queryProject.Take(30).ForEachAsync(async t =>
                {
                    result.Add(
                        await AddOrModifyUserToProject(new AddOrModifyUserToProjectInput
                        {
                            ProjectId = t.Id,
                            UserId = t.CreatorUserId.Value,
                            Position = "",
                            PermissionArray = permissionArray
                        })
                    );
                });
            }
            return result.Count;
        }

        #endregion

        #region 项目模型组

        /// <summary>
        /// 新建/编辑项目模型组
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Guid> CreatOrModifyModelGroup(ProjectModelGroupsDto input)
        {
            #region 表单验证方法

            string error = Validate.ValidateString(new CustomValidate
            {
                FieldName = "模型组名称",
                FieldValue = input.Name,
                IsRequired = true
            });
            if (!error.IsNullOrWhiteSpace()) throw new UserFriendlyException(error);

            #endregion

            if (await projectModelGroupsRepository.CountAsync(x => x.Name == input.Name && x.Id != input.Id && x.ProjectId == input.ProjectId) > 0) throw new UserFriendlyException("模型组名称已存在", "请换个名称再试");

            var entity = await projectModelGroupsRepository.FirstOrDefaultAsync(x => x.Id == input.Id);

            if (entity == null)
            {
                entity = ObjectMapper.Map<ProjectModelGroups>(input);
#if !DEBUG
                entity.CreatorUserName = UserManager.UserName;
#endif
                var modelGroup = await projectModelGroupsRepository.InsertAsync(entity);

                //project
                var project = await projectsRepository.FirstOrDefaultAsync(x => x.Id == entity.ProjectId);

                var parent2 = await documentLibrarysRepository.GetAll().Where(x => x.PrimaryId == project.Id && x.PType == EnumDocumentPType.检验批).FirstOrDefaultAsync();
                //    InsertAsync(new DocumentLibrarys
                //{
                //    Id = Guid.NewGuid(),
                //    Name = EnumDocumentPType.检验批.ToString(),
                //    ParentId = Guid.Empty,
                //    PrimaryId = input.Id,
                //    PType = EnumDocumentPType.检验批,
                //    IsSystem = true
                //});

                //初始化检验批下的场景节点
                await InitDocumentByProject(project, modelGroup, parent2);
                return modelGroup.Id;
            }
            else
            {
                //只编辑模型组信息
                entity.Name = input.Name;
                entity.ImageUrl = input.ImageUrl;
                await projectModelGroupsRepository.UpdateAsync(entity);
                return entity.Id;
            }
        }

        /// <summary>
        /// 删除模型组
        /// </summary>
        /// <param name="input">模型组GroupId</param>
        /// <returns></returns>
        public async Task RemoveModelGroup(EntityDto<Guid> input)
        {
            var entity = await projectModelGroupsRepository.FirstOrDefaultAsync(x => x.Id == input.Id);
            if (entity != null)
            {
                await BatchRemoveModelsByGroup(entity.Id);
                await projectModelGroupsRepository.DeleteAsync(entity);
            }
        }

        /// <summary>
        /// 查询模型组-分页数据集合
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<object>> QueryModelGroupsPagedList(ProjectModelGroupsInput input)
        {
            var query = projectModelGroupsRepository.GetAll()
                        .Where(x => x.ProjectId == input.ProjectId)
                        .WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Filter));

            var items = await query.OrderByDescending(x => x.CreationTime).PageByAsync(input);

            var result = ObjectMapper.Map<List<ProjectModelGroupsDto>>(items);
            var projectsModelList = await projectsModelsRepository.GetAllListAsync(x => x.ProjectId == input.ProjectId);

            foreach (var item in result)
            {
                var list = projectsModelList.Where(x => x.ModelGroupId == item.Id);
                item.TaskId = list.Any() ? item.TaskId : Guid.Empty;
                item.Count = list.Count(); //显示当前场景下的模型总数
            }
            return new PagedResultDto<object>(query.Count(), result);
        }
        #endregion

        #region 项目模型

        /// <summary>
        /// 新建/编辑项目模型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreatOrModifyModel(ProjectModelsDto input)
        {
            if (input.Id == Guid.Empty)
            {
                var projectsModelList = await projectsModelsRepository.GetAllListAsync(x => x.ModelGroupId == input.ModelGroupId);
                if (projectsModelList.Any(x => x.Hash == input.Hash)) throw new UserFriendlyException("文件已存在该场景，请重新上传");
                var entity = ObjectMapper.Map<ProjectModels>(input);
#if !DEBUG
                entity.CreatorUserName = UserManager.UserName;
#endif
                entity.CreatorUserId = UserManager.PrimaryId;
                await projectsModelsRepository.InsertAsync(entity);
            }
            else //只编辑模型信息
            {
                var entity = await projectsModelsRepository.FirstOrDefaultAsync(x => x.Id == input.Id);
                if (entity == null) throw new UserFriendlyException(L("TheModelDoesNotExist"), L("PleaseRefreshThePageAndTryAgain"));
                entity.Name = input.Name;
                entity.ImageUrl = input.ImageUrl;
                entity.Path = input.Path;
                entity.Size = input.Size;
                entity.ModelGroupId = input.ModelGroupId;
                entity.FileName = input.FileName;
                entity.Type = input.Type;
                await projectsModelsRepository.UpdateAsync(entity);
            }
        }

        /// <summary>
        /// 触发转换模型操作
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<object> ConvertModel(ConvertModelsInput input)
        {
            var modelInfo = await projectsModelsRepository.GetConvertModelList(input);

            //CIFileServer.AjaxResponse<dynamic> result1 = null;
            //try
            //{
            //    result1 = await cIFileServerApi.ConvertModel(projectInfo);
            //    return result1;
            //}
            //catch (Exception)
            //{

            //}
            //return result1;

            //var request = new RestRequest($"file/api/v1/FileConvert/convert-model/{input.ModelGroupId}", Method.POST, DataFormat.Json);
            //request.AddHeader("TenantId", Convert.ToBase64String(Encoding.UTF8.GetBytes(input.ProjectId.ToString())));
            //request.AddHeader("Authorization", RefreshTokenService.GetAccessToken());
            //request.AddJsonBody(modelInfo);
            //Logger.Info("\r\n#################################   调用转换输入参数：" + JsonConvert.SerializeObject(modelInfo));
            //var client = new RestClient(appConfiguration["App:FileServerRootAddress"]);//文件服务
            //var response = client.Execute(request);

            var response = await modelInfo.RequestConvertModel(appConfiguration, input.ModelGroupId, input.ProjectId, Logger);
            var flag = response?.StatusCode == System.Net.HttpStatusCode.OK;
            if (flag)
            {
                var result = JsonConvert.DeserializeObject<SyncResult>(response.Content); //批量更新 TaskId，供前端判断转换进度时使用
                await projectsModelsRepository.BatchUpdateAsync(x => new ProjectModels { TaskId = result.Item.BimTask.TaskId, Status = 1 },
                    x => x.ProjectId == input.ProjectId && x.ModelGroupId == input.ModelGroupId); //更新模型文件上的 TaskId

                await projectModelGroupsRepository.BatchUpdateAsync(x => new ProjectModelGroups { TaskId = result.Item.BimTask.TaskId, Status = 1 },
                    x => x.ProjectId == input.ProjectId && x.Id == input.ModelGroupId); //更新场景上的 TaskId
            }
            return response.Content;
        }

        /// <summary>
        /// 触发转换进度查询操作
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> ConvertProcess(ConvertModelsInput input)
        {
            var modelInfo = await projectsModelsRepository.GetConvertModelList(input);
            var responseArray = await modelInfo.RequestConvertProcess(appConfiguration, input.ModelGroupId, input.ProjectId, Logger);
            var result = false;
            foreach (var item in responseArray)
            {
                if (item?.StatusCode != System.Net.HttpStatusCode.OK) continue;
                var modelCouvertProcessApiDto = JsonConvert.DeserializeObject<ModelCouvertProcessResultItemApiDto>(item.Content)?.Item;
                if (!modelCouvertProcessApiDto.GetConvertStatus()) continue;

                var asdf = modelInfo.FirstOrDefault(x => x.TaskId == modelCouvertProcessApiDto.TaskId);
                if (asdf != null) asdf.ConvertStatus = 3;

                await projectsModelsRepository.BatchUpdateAsync(x => new ProjectModels { Status = 3 },
                    x => x.ProjectId == input.ProjectId && x.ModelGroupId == input.ModelGroupId); //更新模型文件上的 转换状态

                if (result = modelInfo.Count(x => x.ConvertStatus == 3) == modelInfo.Count)
                {
                    await projectModelGroupsRepository.BatchUpdateAsync(x => new ProjectModelGroups { Status = 3 },
                        x => x.ProjectId == input.ProjectId && x.Id == input.ModelGroupId); //更新场景上的 转换状态
                }
            }

            return result;
        }

        /// <summary>
        /// 删除模型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task RemoveModel(Guid input)
        {
            var entity = await projectsModelsRepository.FirstOrDefaultAsync(x => x.Id == input);
            if (entity == null) throw new UserFriendlyException(L("TheModelDoesNotExist"), L("PleaseRefreshThePageAndTryAgain"));
            await projectsModelsRepository.DeleteAsync(entity);
        }

        /// <summary>
        /// 批量删除模型组模型
        /// </summary>
        /// <param name="modelGroupId">模型组标识</param>
        /// <returns></returns>
        public async Task BatchRemoveModelsByGroup(Guid modelGroupId)
        {
            await projectsModelsRepository.DeleteAsync(x => x.ModelGroupId == modelGroupId);
        }

        /// <summary>
        /// 批量删除模型
        /// </summary>
        /// <param name="input">模型标识集合</param>
        /// <returns></returns>
        public async Task BatchRemoveModelsByIds(List<Guid> input)
        {
            if (input != null)
                await projectsModelsRepository.DeleteAsync(x => input.Contains(x.Id));
        }

        /// <summary>获取文件访问签名</summary>
        public async Task<string> QueryParameter()
        {
            var appId = appConfiguration["FileAccessSignature:appId"];
            var secretId = appConfiguration["FileAccessSignature:secretId"];
            var secreteKey = appConfiguration["FileAccessSignature:secreteKey"];
            var ticks = Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds);

            return await Task.FromResult($"a={appId}&t={ticks}&at={DetectionSignature(appId, secretId, secreteKey, ticks)}");
        }

        private static string DetectionSignature(string appId, string secretId, string secretKey, double ticks)
        {
            var plainText = $"a={appId}&s={secretId}&t={ticks}";
            using (var mac = new HMACSHA1(Encoding.UTF8.GetBytes(secretKey)))
            {
                var hash = mac.ComputeHash(Encoding.UTF8.GetBytes(plainText));
                var pText = Encoding.UTF8.GetBytes(plainText);
                var all = new byte[hash.Length + pText.Length];
                Array.Copy(hash, 0, all, 0, hash.Length);
                Array.Copy(pText, 0, all, hash.Length, pText.Length);
                return Convert.ToBase64String(all);
            }
        }

        /// <summary>
        /// 查询模型-分页数据集合
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ProjectModelsDto>> QueryModelsPagedList(ProjectsModelsInput input)
        {
            var query = projectsModelsRepository.GetAll()
                        .Where(x => x.ProjectId == input.ProjectId)
                        .WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Filter))
                        .WhereIf(input.ModelGroupId != Guid.Empty, x => x.ModelGroupId == input.ModelGroupId);

            var result = await query.OrderByDescending(x => x.CreationTime).PageByAsync(input);

            return new PagedResultDto<ProjectModelsDto>(query.Count(),
                ObjectMapper.Map<List<ProjectModelsDto>>(result));
        }

        #endregion

        #region 项目模型视图

        /// <summary>
        /// 新建/编辑视图
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Guid> CreatOrModifyView(ProjectViewPortsInput input)
        {
            if (input.Id == Guid.Empty)
            {
                var entity = ObjectMapper.Map<ProjectViewPorts>(input);
                return await projectViewPortsRepository.InsertAndGetIdAsync(entity);
            }
            else
            {
                var entity = await projectViewPortsRepository.FirstOrDefaultAsync(x => x.Id == input.Id);
                if (entity == null) throw new UserFriendlyException(L("TheModelDoesNotExist"), L("PleaseRefreshThePageAndTryAgain"));
                entity.Name = input.Name;
                entity.Url = input.Url;
                entity.Point = input.Point;
                entity.Description = input.Description;
                entity.ModelGroupId = input.ModelGroupId;
                await projectViewPortsRepository.UpdateAsync(entity);
                return entity.Id;
            }
        }

        /// <summary>
        /// 删除视图
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task RemoveView(Guid input)
        {
            if (input == Guid.Empty) throw new UserFriendlyException(L("NoParam"), L("InvalidFormMessage"));
            var entity = await projectViewPortsRepository.FirstOrDefaultAsync(x => x.Id == input);
            if (entity == null) throw new UserFriendlyException(L("TheViewDoesNotExist"), L("PleaseRefreshThePageAndTryAgain"));
            await projectViewPortsRepository.DeleteAsync(entity);
        }

        /// <summary>
        /// 批量删除视图
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task BatchRemoveView(List<Guid> input)
        {
            if (input == null || input.Count <= 0) throw new UserFriendlyException(L("NoParam"), L("InvalidFormMessage"));
            foreach (var id in input) await projectViewPortsRepository.DeleteAsync(id);
        }

        /// <summary>
        /// 获取视图集合-根据标识集合
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<ProjectViewPortsDto>> QueryViewsList(ProjectViewPortsListInput input)
        {
            var result = await projectViewPortsRepository.GetAllListAsync(x => input.IdList.Contains(x.Id));

            return ObjectMapper.Map<List<ProjectViewPortsDto>>(result);
        }

        /// <summary>
        /// 查询视图-分页数据集合
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ProjectViewPortsDto>> QueryViewsPagedList(ProjectsModelsInput input)
        {
            var query = projectViewPortsRepository.GetAll()
                        .Where(x => x.ProjectId == input.ProjectId)
                        .WhereIf(input.ModelGroupId != Guid.Empty, x => x.ModelGroupId == input.ModelGroupId)
                        .WhereIf(input.Type > 0, x => x.Type == input.Type)
                        .WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Filter));

            var result = await query.OrderByDescending(x => x.CreationTime).PageByAsync(input);

            return new PagedResultDto<ProjectViewPortsDto>(query.Count(),
                ObjectMapper.Map<List<ProjectViewPortsDto>>(result));
        }

        #endregion

        #region 检验批相关

        /// <summary>初始化Zhuye项目资料相关目录信息</summary>
        private async Task<DocumentLibrarys> InitDocumentByProject(Projects input, ProjectModelGroups groupInput, DocumentLibrarys parent, bool IsReset = false)
        {
            if (parent == null)
            {
                if (IsReset)
                {
                    //删除所有初始化的节点
                    await documentLibrarysRepository.DeleteAsync(x => x.PrimaryId == input.Id && x.IsSystem == true);
                }

                //检验批
                var parent2 = await documentLibrarysRepository.InsertAsync(new DocumentLibrarys
                {
                    Id = Guid.NewGuid(),
                    Name = EnumDocumentPType.检验批.ToString(),
                    ParentId = Guid.Empty,
                    PrimaryId = input.Id,
                    PType = EnumDocumentPType.检验批,
                    IsSystem = true
                });
                return parent2;
                //await InitDocumentByProject(input, groupInput, parent2);
            }
            else if (parent.PType == EnumDocumentPType.检验批 && groupInput != null)
            {
                #region 默认生成项目场景进度

                var transInfo = "";
                DateTime createdate = DateTime.Now.Date;
                //创建项目场景进度
                var request = new CreateMppProjectInput
                {
                    Id = groupInput.Id,
                    Title = groupInput.Name,
                    StartDate = createdate, //transInfo.FinishTimeRange[0],
                    FinishDate = createdate.AddMonths(1), //transInfo.FinishTimeRange[1],
                    Author = UserManager.UserName,
                    Company = UserManager.UserName
                };
                string MppRequest = JsonConvert.SerializeObject(request);
                Console.WriteLine("###########  33333333333333 ##############");
                //创建进度
                var response = await mppAppService.CreateMppProject(groupInput.Id, request);

                string MppResponse = JsonConvert.SerializeObject(response);
                Console.WriteLine("###########  44444444444444 ##############");
                if (response.Success && response.Item != null && response.Item.Id != Guid.Empty)
                {
                    transInfo = JsonConvert.SerializeObject(new { MppId = response.Item.Id });
                }

                #endregion

                //创建场景
                var parent1 = await documentLibrarysRepository.InsertAsync(new DocumentLibrarys
                {
                    Id = groupInput.Id, //Guid.NewGuid(),
                    Name = groupInput.Name,
                    ParentId = parent.Id,
                    //PrimaryId2= groupInput.Id,
                    PrimaryId = input.Id,
                    PType = EnumDocumentPType.场景,
                    IsSystem = true,
                    MppRequest = MppRequest,
                    MppResponse = MppResponse,
                    MppCreateTime = createdate
                });
                //await InitDocumentByProject(input, groupInput, parent1);
            }
            else if (parent.PType == EnumDocumentPType.场景)
            {
                //按照模板导入分部分项信息
                //await InitDocumentByCategoryTemplate();
            }

            return null;
        }

        #endregion
    }
}
